home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 1 / Meeting Pearls Vol 1 (1994).iso / installed_progs / comm / ums / developer.lha / Developer / doc / ums.doc
Encoding:
Text File  |  1993-09-23  |  46.0 KB  |  1,224 lines

  1. TABLE OF CONTENTS
  2.  
  3. ums.library/--background--
  4. ums.library/CannotExport
  5. ums.library/DeleteUMSMsg
  6. ums.library/ExportedMsg
  7. ums.library/FreeUMSConfig
  8. ums.library/FreeUMSMsg
  9. ums.library/LogUMS
  10. ums.library/ReadUMSConfig
  11. ums.library/ReadUMSMsg
  12. ums.library/UMSErrNum
  13. ums.library/UMSErrTxt
  14. ums.library/UMSLogin
  15. ums.library/UMSLogout
  16. ums.library/UMSRLogin
  17. ums.library/UMSSearch
  18. ums.library/UMSSelect
  19. ums.library/WriteUMSConfig
  20. ums.library/WriteUMSMsg
  21. ums.library/--background--                         ums.library/--background--
  22.  
  23.        $VER: 10.21 (28-Aug-93)
  24.  
  25.        COPYRIGHT
  26.  
  27.          This document is (C) 1992 by Martin Horneffer.
  28.  
  29.          It may freely be copied and distributed, as long as the text is
  30.        unchanged and this copyright notice is left intact.
  31.  
  32.        GENERAL
  33.  
  34.          UMS stands for "Universal Message System".
  35.  
  36.          This  means  that  UMS  allows  to  treat  and read all kinds of
  37.        messages  ('e-mail'  and 'news') as universally and efficiently as
  38.        possible.
  39.  
  40.          The  user  should  not need to care about what network a message
  41.        comes  from  or goes to/through and what format is used, he or she
  42.        should be able to concentrate totally on the messages' contents.
  43.  
  44.          In order to achieve this goal, UMS does two things:
  45.  
  46.          1) define an universal format for messages where messages in all
  47.        formats  and  from  all  networks can be stored in without loss of
  48.        information and nevertheless being randomly interchangeable.
  49.  
  50.          2) implement  a central, network-independent database-mamagement
  51.        that  allows to store and read/retrieve messages in the UMS format
  52.        as efficiently as possible.
  53.  
  54.          For  the message format, please read the separate documentation.
  55.  
  56.          The  implementation  of  the  Message  Base Processor ('MBP') is
  57.        based  on  the server/client- concept.  Clients address the server
  58.        to  get  or  put  messages.   The  server  manages the storage and
  59.        retrieval   of   messages  and  controls  the  different  client's
  60.        access-rights  to the system.  The common interface between client
  61.        and server is a set of functions described in this document.
  62.  
  63.          Clients are
  64.          -  simple  USERS  that  read  and write messages (using programs
  65.        called 'newsreaders'),
  66.          -  a  special  kind  of  user, the 'SYSOP', which has additional
  67.        rights and tools to administer the system,
  68.          -  IMPORTERS,  that get messages form other systems and put them
  69.        into the local system after converting them to the UMS format, and
  70.          -  EXPORTERS,  that  look for all NEW messages in the system and
  71.        send them to other systems after converting them into the specific
  72.        format.
  73.  
  74.          The  MBP  controls  which user may read what message and, in the
  75.        same  way, which exporter needs to export or forward what message.
  76.        It  cares  about whether a message can or cannot be correctly sent
  77.        to its destination.
  78.          The  MBP  also  performs  dupe-checking  and  reply-chaining  on
  79.        Message-IDs.
  80.  
  81.  
  82.        TAGS
  83.  
  84.          UMS uses some bit-masking in tag values to indicate some special
  85.        types of tag data:
  86.  
  87.          if  bit 13 is set (tag & 0x2000), the tag data is a STRPTR, i.e.
  88.        a pointer to a null-terminated string.
  89.  
  90.          if  bit  14 is set (tag & 0x4000), the tag is considered a 'var-
  91.        parameter'  (e.g.  LONG *).  I.e.  the tag.data entry must contain
  92.        a  pointer  to  the  real  data,  which will be set/changed by the
  93.        called function.
  94.  
  95.          if both bits 13 and 14 are set ((tag & 0x6000)==0x6000), the tag
  96.        is a pointer to a string pointer which will be set/changed (STRPTR
  97.        *).
  98.  
  99.          if none of these bits is set, the data in most cases is a simple
  100.        integer parameter (e.g.  LONG or LONGBITS).
  101.  
  102. ums.library/CannotExport                             ums.library/CannotExport
  103.  
  104.    NAME
  105.        CannotExport -- Mark a message as not being exportable.
  106.  
  107.    SYNOPSIS
  108.        CannotExport( login, msgNum, error )
  109.                       D2      D3     D4
  110.  
  111.        VOID CannotExport( LONG, LONG, STRPTR );
  112.  
  113.    FUNCTION
  114.          Tell  the  MBP  that  you cannot export this message, due to any
  115.        reason.   The MBP will then look if other exporters still could be
  116.        able to export the message or do some error processing otherwise.
  117.          It may use the supplied error-string therein.  This error-string
  118.        should  be  a  short  description  why  the  message  could not be
  119.        exported.  By convention it should not be longer than 80 bytes.
  120.  
  121.    INPUTS
  122.        msgNum - Number of the message.
  123.        error  - Short string (<80 chars).
  124.  
  125.    NOTES
  126.          This function may only be called by exporters.
  127.          See also ExportedMsg().
  128.  
  129.    BUGS
  130.          The  MBP currently does not write a bounce mail to the author of
  131.        the mail, but sets a special global bit instead, which would allow
  132.        a 'bounce daemon' to automatically write bounce mails.
  133.  
  134.    SEE ALSO
  135.        ExportedMsg()
  136.  
  137. ums.library/DeleteUMSMsg                             ums.library/DeleteUMSMsg
  138.  
  139.    NAME
  140.        DeleteUMSMsg -- Delete a message.
  141.  
  142.    SYNOPSIS
  143.        success = DeleteUMSMsg( login, msgNum )
  144.          D0                     D2      D3
  145.  
  146.        BOOL DeleteUMSMsg( LONG, LONG);
  147.  
  148.    FUNCTION
  149.          This  functions deletes a message, specified by number, from the
  150.        UMS MB.
  151.          It does not necessarily free space on the hd, but it removes the
  152.        message  logically from the MB so that no other user can access it
  153.        anymore and it won't affect the dupe-check for new messages.
  154.          The  MBP  may need reorganization to physically remove logically
  155.        deleted messages.
  156.  
  157.    INPUTS
  158.        msgNum  -  Number  of  the  message to be deleted.  As returned by
  159.                   UMSSearch() or WriteUMSMsg().
  160.  
  161.    RESULT
  162.        success  -  Inidcates  whether the message was actually deleted or
  163.                    not.   It  will  be  not  deleted  if  you  don't have
  164.                    write-access  to  this  message or the message doesn't
  165.                    exist.
  166.  
  167.    NOTES
  168.          The  number of a message is valid only as long as you are logged
  169.        in.  After UMSLogout() messages numbers may change!
  170.          So  you  always  have  to  use the real Message-ID to remember a
  171.        message persistently.
  172.  
  173. ums.library/ExportedMsg                               ums.library/ExportedMsg
  174.  
  175.    NAME
  176.        ExportedMsg -- Mark a message as being successfully exported.
  177.  
  178.    SYNOPSIS
  179.        ExportedMsg( login, msgNum )
  180.                      D2      D3
  181.  
  182.        VOID ExportedMsg( LONG, LONG );
  183.  
  184.    FUNCTION
  185.          Tells  the  MBP  that  a message has been successfully exported.
  186.        The  MBP  uses  this  information  to prevent other exporters from
  187.        wrongly  exporting  this message a second time or writing a bounce
  188.        message.
  189.  
  190.          Every  exporter that exports a message from the local UMS system
  191.        to  any  other system or network MUST call either ExportedMsg() or
  192.        CannotExport()  for  each message it has processed.  This is valid
  193.        for  private  messages as well as for public messages (news).  The
  194.        MBP will decide what has to be done in any of these cases.
  195.  
  196.    INPUTS
  197.        msgNum - Number of the exported message.
  198.  
  199.    NOTES
  200.          This function may only be called by exporters.
  201.  
  202.    SEE ALSO
  203.        CannotExport()
  204.  
  205. ums.library/FreeUMSConfig                           ums.library/FreeUMSConfig
  206.  
  207.    NAME
  208.        FreeUMSConfig -- Free a string returned by ReadUMSConfig().
  209.  
  210.    SYNOPSIS
  211.        FreeUMSConfig( login, string)
  212.                        D2      D3
  213.  
  214.        FreeUMSConfig( LONG, STRPTR);
  215.  
  216.    FUNCTION
  217.          Frees  the  buffer  for  a  string  allocated  and  returned  by
  218.        ReadUMSConfig().   After 'FreeUMSConfig(string)', 'string' will be
  219.        invalid.
  220.  
  221.    INPUTS
  222.        string - string returned by ReadUMSConfig().
  223.  
  224.    SEE ALSO
  225.        ReadUMSConfig()
  226.  
  227. ums.library/FreeUMSMsg                                 ums.library/FreeUMSMsg
  228.  
  229.    NAME
  230.        FreeUMSMsg -- Free buffers associated with a certain message.
  231.  
  232.    SYNOPSIS
  233.        FreeUMSMsg( login, msgNum )
  234.                     D2      D3
  235.  
  236.        FreeUMSMsg( LONG, LONG );
  237.  
  238.    FUNCTION
  239.          Frees  all  the  buffers  associated  with  a  certain  message.
  240.        ReadUMSMsg() allocates the buffers, this function frees them.
  241.  
  242.    INPUTS
  243.        msgNum - number of the message previously read with ReadUMSMsg().
  244.  
  245.    NOTES
  246.          With  FreeUMSMsg()  all  STRPTRs obtained with ReadUMSMsg() that
  247.        are  concerned  with this certain message become invalid.  You can
  248.        have  multiple  ReadUMSMsg()  on  the  same  message  but only one
  249.        FreeUMSMsg().
  250.  
  251.    SEE ALSO
  252.        ReadUMSMsg()
  253.  
  254. ums.library/LogUMS                                         ums.library/LogUMS
  255.  
  256.    NAME
  257.        LogUMS -- Write an entry to the global UMS logfile.
  258.  
  259.    SYNOPSIS
  260.        LogUMS( login, level, format, args )
  261.                  D2    D4      D5     D6
  262.  
  263.        LogUMS( LONG, LONG, STRPTR, LONG * );
  264.  
  265.        LogUms( login, level, format, ... )
  266.  
  267.        LogUms( LONG, LONG, STRPTR, ... )
  268.  
  269.    FUNCTION
  270.          Write  a  short  message  to the UMS logfile, doing printf-style
  271.        formatting on supplied parameters.
  272.          Rather  than creating all its own logfile, an application should
  273.        use this function to report its actions and/or errors.  This makes
  274.        it  easier for the user to get an overview on what is happening in
  275.        his system - he only has to look in ONE logfile.
  276.          LogUMS()  uses  a  'level'-parameter to decide whether a message
  277.        should  actually  be  written  to  the logfile or be ignored.  The
  278.        lower  this  number, the more important is the message.  Choose it
  279.        as follows:
  280.  
  281.          1-4:  an ERROR.  1=very fatal error, 4=recoverable error.
  282.          5-7:  general information or report.
  283.          8-9:  information that is not useful for normal operation, but
  284.                used for debugging purposes.
  285.  
  286.          Of  course  messages with higher level-values should appear more
  287.        frequently than those with low level-values.
  288.  
  289.    INPUTS
  290.          level - Number between 1 and 9.
  291.         format - Printf-style format-string.  See RawDoFmt() for more
  292.                  information on formatting.
  293.           args - Arguments for the format-string.
  294.  
  295.    SEE ALSO
  296.        RawDoFmt()
  297.  
  298. ums.library/ReadUMSConfig                           ums.library/ReadUMSConfig
  299.  
  300.    NAME
  301.        ReadUMSConfig -- Read something from the global configuration.
  302.  
  303.    SYNOPSIS
  304.        string = ReadUMSConfig( login, tags )
  305.          D0                     D2     D3
  306.  
  307.        STRPTR ReadUMSConfig( LONG, struct TagIten * );
  308.  
  309.        string = ReadUMSConfigTags( login, tag1, ... )
  310.  
  311.        STRPTR ReadUMSConfigTags( LONG, ULONG, ... );
  312.  
  313.    FUNCTION
  314.          Read a config object from the global UMS configuration.
  315.  
  316.          Whenever  possible,  applications  should  use  the  global  UMS
  317.        configuration and this function instead of extra config-files.
  318.  
  319.          A  'config-string'  is a null-terminated string identified by an
  320.        unique   name.    Similar   to  shell-  and  environment-variables
  321.        config-strings  can  be global (same for all users) or local (only
  322.        visible to a certain user).
  323.  
  324.          Other   config-objects  are  'users'  (with  aliases  and  local
  325.        strings), 'akas' and 'netgroups'.
  326.  
  327.          In   order   not   to   mix  up  config-strings  of  different
  328.        applications,  their  names  should have the id of the application
  329.        and  a  dot  prepended.   E.g.   "fido.outbound",  "fido.inbound",
  330.        "uucp.uuspool", "magicmail.publicScreenName", etc.
  331.          The  MBP  enforces  this  convention  by  not  accepting  config
  332.        elements without a dot (".").
  333.  
  334.          Names for config elements are case-insensitive.
  335.  
  336.          This function buffers the returned string until it is freed with
  337.        FreeUMSConfig() or (UMSLogout()).
  338.  
  339.    INPUTS
  340.          The following tags are allowed:
  341.  
  342.          CfgGlobalOnly         : (none)
  343.                read just global config-elements, ignore local ones.
  344.  
  345.          CfgUser               : STRPTR
  346.                read  config  elements  local  to  another user.  You must
  347.        specify  the  name  of  the  other  user  here.   This contradicts
  348.        CfgGlobalOnly!
  349.  
  350.          CfgMatchPattern       : STRPTR
  351.                (Not yet implemented in V9.)
  352.                Only  search  for  config  elements  that  match  a  given
  353.        pattern.
  354.  
  355.  
  356.          The  following  tags are mutually exclusive.  Use exactly one of
  357.        them.
  358.  
  359.          CfgName               : STRPTR
  360.                read a config-string with given name.
  361.  
  362.          CfgUserName           : STRPTR
  363.                get the 'realname' for a user with a given alias.
  364.  
  365.          CfgNextVar                    : STRPTR
  366.                get  the name of the next config variable. This allows you
  367.        to  scan  all  existing variables. On first invocation you set the
  368.        tag's  data  to  NULL  and get the name of the first var. Then you
  369.        always  set  it  to  what has been returned on the last call. When
  370.        NULL is returned, you're finished.
  371.                Can  (but  needn't)  be combined with tag CfgGlobalOnly or
  372.        tag CfgUser.
  373.  
  374.  
  375.          CfgSameNetgroup       : STRPTR
  376.                (Not yet implemented in V9)
  377.                get the next groupname for the same netgroup.
  378.                Any  number  of groupnames  may be configured as identical
  379.        'netgroups'.  Using this tag you can get another name for the same
  380.        'netgroup'  as the given groupname.  Using this tag repeatedly you
  381.        can  cycle trough all names for the same group.  Because these are
  382.        organized  in  a  circular  structure you must do a string-compare
  383.        with  the  original  string to detect when you are finished.  This
  384.        returns  NULL  only  when  the  given  string  doesn't  indicate a
  385.        netgroup.
  386.  
  387.          CfgNextNetgroup       : STRPTR
  388.          CfgNextUser           : STRPTR
  389.          CfgNextAlias          : STRPTR
  390.                (Not yet implemented in V9)
  391.                These  tags  allow  you to scan all existing configuration
  392.        objects.   On  first invocation you set the tag's data to NULL and
  393.        get the name of the first element.  Then you always set it to what
  394.        has been returned on the last call.  When NULL is returned, you're
  395.        finished.
  396.                You   may  use  CfgUser  together  with  CfgNextAlias  and
  397.        CfgNextString.  CfgGlobalOnly is redundant as it's the default.
  398.  
  399.    RESULT
  400.        string - a pointer to the desired config element, or NULL.
  401.  
  402.    BUGS
  403.              Some  of  the  tags  are not implemented yet (as indicated).
  404.        Tell the author (Martin Horneffer) when you need them!
  405.  
  406.    SEE ALSO
  407.        FreeUMSConfig(), WriteUMSConfig()
  408.  
  409. ums.library/ReadUMSMsg                                 ums.library/ReadUMSMsg
  410.  
  411.    NAME
  412.        ReadUMSMsg -- Read (parts of) a message.
  413.  
  414.    SYNOPSIS
  415.        success = ReadUMSMsg( login, tags )
  416.          D0                   D2     D3
  417.  
  418.        BOOL ReadUMSMsg( LONG, struct TagItem * );
  419.  
  420.        success = ReadUMSMsgTags( login, tag1, ... )
  421.  
  422.        BOOL ReadUMSMsgTags( LONG, ULONG, ... );
  423.  
  424.    FUNCTION
  425.          Read a message or any parts of it.
  426.  
  427.    INPUTS
  428.          The following tags are allowed:
  429.  
  430.          RMsgNum               : LONG
  431.                specify which msg to read. This tag MUST be used!
  432.  
  433.          RHeaderLength         : LONG *
  434.                you have to pass a pointer to a LONG here.  This LONG will
  435.        be  set  to  the length of the message-header in bytes.  I.e.  the
  436.        length  of all text-fields considered to belong to the 'header' of
  437.        a message.
  438.  
  439.          RTextLength           : LONG *
  440.                like  RHeaderLength,  but  the length of the message-text.
  441.        These are all other fields.
  442.  
  443.          RMsgDate              : LONG *
  444.                the  date the message has been written to the message-base
  445.        (also  referred  to  as  the  'receive-date').  In AmigaDOS Format
  446.        (seconds since 1.1.1978).
  447.  
  448.          RChainUp,
  449.          RChainDn,
  450.          RChainLt,
  451.          RChainRt              : LONG *
  452.                reply-chaining.   Since  a  message  can only refer to one
  453.        other  (older)  message,  but have multiple other (newer) messages
  454.        referring  to  it, a tree is built out of this 'comment-chaining'.
  455.        ChainUp  points to the referred message.  ChainDn points to one of
  456.        the messages that comment on the current one.  ChainLt and ChainRt
  457.        point to other messages which share the same ChainUp.
  458.                The  LONG  you  supply a pointer to in the tag's data will
  459.        either  be  set  to  zero  (when there is no such chain) or to the
  460.        number of a message.
  461.  
  462.          RGlobalFlags          : LONGBITS *
  463.                global  flags  for  this message.  In the MB every message
  464.        has  exactly one set of global flags.  See <ums.h> for the meaning
  465.        of these flags.
  466.  
  467.          RUserFlags            : LONGBITS *
  468.                user-flags for this message.  Every user of the MB has one
  469.        set  of user-flags for each message.  See <ums.h> for the fixed or
  470.        suggested meanings of these flags.
  471.  
  472.          RLoginFlags           : LONGBITS *
  473.                login-flags  for  this message.  Every login has a private
  474.        set  of  flags  for  each  message.   In  contrast  to  global  or
  475.        user-flags,  login-flags  are NOT saved and vanish on UMSLogout().
  476.        They are set to zero on UMSLogin().
  477.  
  478.          RHardLink,
  479.          RSoftLink             : LONG *
  480.                a  pointer  to another link in the circular linked list of
  481.        linked  messages.   Zero  if  a  real  message  (no  link).  Since
  482.        message-links can be either hard or soft, but not both at the same
  483.        time, only one of these can be non-zero.
  484.  
  485.          RDateStyle            : LONG
  486.                use  this  tag and set its data to 1 if you want to get an
  487.        old-style  'receive-date'.   Don't use this tag or set its data to
  488.        zero otherwise.
  489.  
  490.          RMsgText, ..
  491.          RMsgText + 127        : STRPTR *
  492.                tell  UMS  that  you want to read the specified text-field
  493.        and  supply a place for a pointer to it.  This will be set to NULL
  494.        if  the  field  doesn't  exist  or  you're not allowed to read it.
  495.  
  496.          RTextFields           : UMSMsgTextFields
  497.                if  you  supply  a pointer to an array of 128 STRPTR here,
  498.        it  will  be  set  to  the read text-fields.  Useful for reading a
  499.        whole  message  without  having to specify a tag for each possible
  500.        text-field.
  501.  
  502.          RReadHeader           : (none)
  503.                tell  UMS  that you want to read all header-field.  Useful
  504.        in combination with RTextFields only.
  505.  
  506.          RReadAll              : (none)
  507.                tell  UMS  that  you  want  to read the message-text, too.
  508.        Useful in combination with RTextFields only.
  509.  
  510.  
  511.        The following tag was not implemented in ums.library until V9.70 !
  512.  
  513.          RIDStyle              : LONG
  514.                choose  the  style  of  local  message IDs.  There are two
  515.        possible  formats of 'local' message IDs (= the IDs created by the
  516.        local system):
  517.  
  518.                a)  a  simple  decimal  number that is unique on the local
  519.        system
  520.                b)  this  decimal  number  followed by "@" and the domain-
  521.        address of the local system.  This conforms with RFC822/1036.
  522.  
  523.                Old  (obsolete) Version of ums.library (< V9.70) still use
  524.        format a), but since V9.70 versions use format b) in order to make
  525.        things cleaner and make life easier for exporters.  With format a)
  526.        exporters  must  append the domain-address to IDs themselves, with
  527.        format b) they needn't care about whether an ID is local or not.
  528.  
  529.                As  an  interim  solution  this  tag allows to specify the
  530.        desired  format.  Its  data set to 1 forces format a), 0 (default)
  531.        forces format b).
  532.  
  533.          RNoUpdate        : LONG
  534.                when  reading  its  message-text,  a  message  is  usually
  535.        updated  by having its 'Old'-flag set in your user-status.  If you
  536.        don't  want  the Old-flag to be set, use this tag and set its data
  537.        to 1.
  538.  
  539.    RESULT
  540.        success  - whether your attempt to read the message was successful
  541.                   or not.
  542.  
  543.    NOTES
  544.          The  message  will  be  buffered,  so you can easily use all the
  545.        returned  STRPTRs.   You  have  to  use  FreeUMSMsg()  to free the
  546.        buffers allocated for a certain message.
  547.  
  548.          An  user or exporter usually wants to read a single message only
  549.        once.
  550.          To  make  this  easy, ReadUMSMsg() checks whether the user reads
  551.        the 'MsgText' of a message, and, if so, sets the 'Old'-Flag in the
  552.        users status if it wasn't already set.
  553.          So  the  user (or exporte) only needs to ask for this flag to be
  554.        unset  when  using  'UMSSearch()'  before  'ReadUMSMsg()' and will
  555.        automatically avoid reading the same message a second time.
  556.  
  557.    SEE ALSO
  558.        FreeUMSMsg(), UMSSearch()
  559.  
  560. ums.library/UMSErrNum                                   ums.library/UMSErrNum
  561.  
  562.    NAME
  563.        UMSErrNum -- Return the number of the last error.
  564.  
  565.    SYNOPSIS
  566.        error = UMSErrNum( login )
  567.         D0                 D2
  568.  
  569.        WORD UMSErrNum( LONG );
  570.  
  571.    FUNCTION
  572.          UMS  functions usually  return  zero to indicate an error.  When
  573.        this  happens,  this  routine may be called to get a more specific
  574.        error code.
  575.          By  some  means,  this  routine  corresponds  to an UMS login as
  576.        dos.library/IoErr() does to a DOS-process.
  577.  
  578.    INPUTS
  579.        login - Login handle as returned by UMSLogin() or UMSRLogin().
  580.  
  581.    RESULT
  582.        error - an error number
  583.  
  584.          Possible UMS error numbers can be grouped into 4 ranges:
  585.  
  586.        0:
  587.          no error at all, the last UMS function call was successful.
  588.  
  589.        100-199:
  590.          a  slight  error.   The  last functions call was not successful,
  591.        but  may  succeed  if  some  slight  changes  will  be made to its
  592.        parameters.   E.g.   when an importer tries to import a message it
  593.        migth get error '103' when the to-user does not exist on the local
  594.        system.   It then should  change  some  message-fields in order to
  595.        forward the message to the sysop.
  596.  
  597.        200-299:
  598.          a real error.  The last function call was not successful  at all
  599.        and should not be retried.
  600.  
  601.        300-:
  602.          a  severe  error  concerning the whole system.  E.g.  the server
  603.        has  terminated.   A  program receiving such an error is recommend
  604.        to UMSLogout() and terminate asap.
  605.  
  606.    SEE ALSO
  607.        UMSErrTxt()
  608.  
  609. ums.library/UMSErrTxt                                   ums.library/UMSErrTxt
  610.  
  611.    NAME
  612.        UMSErrTxt -- Return a string describing the last error.
  613.  
  614.    SYNOPSIS
  615.        text = UMSErrTxt( login )
  616.         D0                D2
  617.  
  618.        STRPTR UMSErrTxt( LONG );
  619.  
  620.    FUNCTION
  621.          When an UMS functions fails and/or UMSErrNum() returns a nonzero
  622.        value,  you  should  use  this  routine  to  get  a  brief English
  623.        description of the last error.
  624.          Interactive  programs  should  display  this  text  to the user.
  625.        Non-interactive programs should use this text in their logfile.
  626.  
  627.    INPUTS
  628.        login - Login handle as returned by UMSLogin() or UMSRLogin().
  629.  
  630.    RESULT
  631.        text - Pointer to a String.
  632.  
  633.    NOTES
  634.          This is similiar to dos.library/Fault(), but it doesn't copy any
  635.        string, it just returns a pointer.
  636.  
  637.          You may NEVER change the string returned by UMSErrTxt()!
  638.  
  639. ums.library/UMSLogin                                     ums.library/UMSLogin
  640.  
  641.    NAME
  642.        UMSLogin -- Open the UMS MB for a certain user.
  643.  
  644.    SYNOPSIS
  645.        login = UMSLogin( user, passwd )
  646.          D0               D2     D3
  647.  
  648.        LONG UMSLogin( STRPTR, STRPTR );
  649.  
  650.    FUNCTION
  651.          Opens  the  MB,  checking  the  password and returning a 'login'
  652.        handle  when  successful.   The given 'user'-name must be known to
  653.        the MBP and the password 'passwd' must match.  If the MBP does not
  654.        already run, it will be automatically started.
  655.          All  other  functions  in  ums.library  requiry  a valid 'login'
  656.        handle to work.
  657.  
  658.    INPUTS
  659.        user   - Name or 'alias' of an user known to the MBP.
  660.        passwd - The user's correct password. A pointer to the null-string
  661.                 is allowed, NULL itself isn't.
  662.  
  663.    RESULT
  664.        login  - Internally used handle to track and remember resources
  665.                 associated  with each  Login.   Different  for a single
  666.                 user's  multiple  Logins.  One Login may be used only by
  667.                 one process at a time.
  668.                 Greater 0 on success, lower or equal 0 on failure.
  669.  
  670.    EXAMPLE
  671.        long login = UMSLogin( "Martin Horneffer", "secret");
  672.  
  673.    NOTES
  674.          If  multiple  MBPs  are running on the same machine, you may use
  675.        UMSRLogin() to specify which one to use.
  676.  
  677.    SEE ALSO
  678.        UMSRLogin(), UMSLogout()
  679.  
  680. ums.library/UMSLogout                                   ums.library/UMSLogout
  681.  
  682.    NAME
  683.        UMSLogout -- Close a Login and free its resources.
  684.  
  685.    SYNOPSIS
  686.        UMSLogout( login )
  687.                    D2
  688.  
  689.        VOID UMSLogout( LONG );
  690.  
  691.    FUNCTION
  692.          Close  a  Login obtained with UMSLogin() or UMSRLogin() and free
  693.        all related resources.
  694.  
  695.    INPUTS
  696.        login - Login handle as returned by UMSLogin() or UMSRLogin().
  697.  
  698.    BUGS
  699.          Used to need much stack under some circumstances, thus crashing some
  700.        programs.  This should be fixed now (V9.66).
  701.  
  702.    SEE ALSO
  703.        UMSLogin(), UMSRLogin()
  704.  
  705. ums.library/UMSRLogin                                   ums.library/UMSRLogin
  706.  
  707.    NAME
  708.        UMSRLogin -- Open a certain UMS MB for a certain user.
  709.  
  710.    SYNOPSIS
  711.        login = UMSRLogin( server, user, passwd )
  712.          D0                 D2     D3     D4
  713.  
  714.        LONG UMSRLogin( STRPTR, STRPTR, STRPTR );
  715.  
  716.    FUNCTION
  717.          Like  UMSLogin(),  but  specifies  a  special  MB.  This permits
  718.        having multiple MBPs running on the same machine.  It will also be
  719.        used for specifying a MBP on a local network.
  720.  
  721.    INPUTS
  722.        server - Name of the MB.
  723.        user   - Name or 'alias' of an user know to the MBP.
  724.        passwd - The user's correct password. A pointer to the null-string
  725.                 is allowed, NULL itself isn't.
  726.  
  727.    RESULT
  728.        login  - Internally used handle to track and remember resources
  729.                 associated  with  each  Login.   Different  for a single
  730.                 user's  multiple  Logins.  One Login may be used only by
  731.                 one process at a time.
  732.                 Greater 0 on success, lower or equal 0 on failure.
  733.  
  734.    EXAMPLE
  735.        long login = UMSRLogin( "test-server", "Martin Horneffer", "secret");
  736.  
  737.    NOTES
  738.          UMSRLogin(  "",  x, y) and UMSRLogin( NULL, x, y) both are equal
  739.        to UMSLogin( x, y).
  740.  
  741.    SEE ALSO
  742.        UMSLogin(), UMSLogout()
  743.  
  744. ums.library/UMSSearch                                   ums.library/UMSSearch
  745.  
  746.    NAME
  747.        UMSSearch -- Search a message from the MB.
  748.  
  749.    SYNOPSIS
  750.        msgNum = UMSSearch( login, tags )
  751.          D0                 D2     D3
  752.  
  753.        LONG UMSSearch( LONG, struct TagItem * );
  754.  
  755.        msgNum = UMSSearchTags( login, tag1, ... )
  756.  
  757.        LONG UMSSearchTags( LONG, ULONG, ... );
  758.  
  759.    FUNCTION
  760.          Search  the  first  (or  next)  message in the MB that fullfills
  761.        certain criteria.
  762.  
  763.          When  you  want  to  read  certain  messages  from the MB, it is
  764.        recommended that you first select these  messages with UMSSelect()
  765.        and  then  alternately  use  UMSSearch()  and ReadUMS() to get all
  766.        these messages.
  767.  
  768.    INPUTS
  769.          Allowed tags:
  770.  
  771.          SearchLast            : LONG
  772.                specify  the  last message NOT to search.  This tag allows
  773.        you  to  cycle  trough all messages fullfilling the same criteria:
  774.        set this to zero and invoke UMSSearch() the first time.  Check the
  775.        result  and  if  it's  not  zero,  put  it  in this tag and invoke
  776.        UMSSearch() again.  Repeat this until it returns zero.
  777.  
  778.          SearchDirection       : LONG
  779.                set  the  search  direction.   1  means search forward (to
  780.        higher  numbers), -1 means search backwards (to lower numbers) and
  781.        0  lets  the  MBP  decide  what  sequence to use.  This needn't be
  782.        exactly  forwards  or  backwards.   It  might  be  in a completely
  783.        different order.
  784.                When you don't depend on a certain search-direction, use 0
  785.        or omit this tag.
  786.  
  787.          SearchGlobal          : (none)
  788.          SearchLocal           : (none)
  789.          SearchUser            : STRPTR
  790.          SearchMask            : LONGBITS
  791.          SearchMatch           : LONGBITS
  792.                search   for   a   matching  status;  like  SelReadGlobal,
  793.        SelReadLocal, SelReadUser, SelMask and SelMatch with UMSSelect().
  794.  
  795.          WMsgText, ..
  796.          WMsgText + 127        : STRPTR
  797.                search  for a matching text; as for UMSSelect().  Only one
  798.        field can be searched for at a time.
  799.  
  800.          SearchQuick           : (none)
  801.                Enable 'quick-search'.  This must be combined with exactly
  802.        one  of  WMsgText+1  ..  WMsgText+31.  quick-searches are possible
  803.        for  exact  string  searches  only, they must not be combined with
  804.        patterns and they are only possible for fields that have an index.
  805.                They  don't  guarantee  that  the returned message's field
  806.        actually  matches  the  given  string,  altough  mistakes are very
  807.        unlikely.
  808.                But they are fast! (see NOTES below)
  809.  
  810.          SearchPattern         : LONG
  811.                indicate whether the string to be searched for is an exact
  812.        string  (0), an AmigaDOS pattern (1) or UMS should try to find out
  813.        (2).
  814.  
  815.    RESULT
  816.        msgNum - numer of a/the searched message; zero if not found.
  817.  
  818.    NOTES
  819.          Although  LONGBITS  are  used  in  the  definition,  the current
  820.        implementation only uses/supports the lower 16 bits.
  821.  
  822.          Performance:   when  searching  for  strings, different calls to
  823.        UMSSearch()  may  significantly  vary  in  performance.  There are
  824.        three general possibilities:
  825.  
  826.          1) quick-searches:
  827.        very fast, no access to the hard-disk needed (once the right index
  828.        is  loaded  into  memory).   Only  possible  if  tag 'SearchQuick'
  829.        specified.
  830.  
  831.          2) indexed searches:
  832.        fast,  in most cases only one, short access to hd is needed; a few
  833.        more   in   really   bad  situations.   If  the  'header'-file  is
  834.        sufficiently  buffered, no accesses to the hd may occur.  Possible
  835.        if searching for exact strings in indexed fields.
  836.  
  837.          3) other searches (non-indexed or patterns):
  838.        slow,  many  data  will  have  to  be  read from hd.  If the field
  839.        searched for is in the 'header'-file and it's heavily buffered, no
  840.        accesses  to  the  hd  may  occur.   Nevertheless  the search will
  841.        consume much CPU-time.
  842.  
  843.          Search for status!!!
  844.  
  845.          Searching for a matching status only (i.e.  not searching for a
  846.        string) is always very fast.
  847.  
  848.          When doing non-indexed- or pattern-search, combine with status
  849.        to reduce the amount of data to be searched through!
  850.  
  851.    SEE ALSO
  852.        UMSSelect(), ReadUMS(), <ums.h>
  853.  
  854. ums.library/UMSSelect                                   ums.library/UMSSelect
  855.  
  856.    NAME
  857.        UMSSelect -- Select messages.
  858.  
  859.    SYNOPSIS
  860.        count = UMSSelect( login, tags )
  861.         D0                 D2     D3
  862.  
  863.        LONG UMSSelect( LONG, struct TagItem * );
  864.  
  865.        count = UMSSelectTags( login, tag1, ... )
  866.  
  867.        LONG UMSSelectTags( LONG, ULONG, ... );
  868.  
  869.    FUNCTION
  870.          Select  messages  in  the  MB according to various criteria.  To
  871.        'select'  here means to set or unset some flags, which then can be
  872.        used by UMSSearch(), stored or transferred to another user.
  873.  
  874.          UMSSelect()  can  only  do  one operation upon every invocation.
  875.        An  operation  usually  looks  for  all messages that fullfill the
  876.        specified criteria and then selects them in a specified way.
  877.  
  878.          When  you  want  to  select  messages  by  different,  logically
  879.        combined criteria, you may need to call UMSSelect() more than once
  880.        and  use  some  temporary  flags.  However, very few calls to this
  881.        functions usually should suffice.
  882.  
  883.    INPUTS
  884.  
  885.          The  following  tags  control  the selection of messages.  Thus,
  886.        they somehow specify the 'output' of the select operation.
  887.  
  888.          SelWriteGlobal        : (none)
  889.                manipulate global flags on the selected messages.
  890.  
  891.          SelWriteLocal         : (none)
  892.                manipulate your local login-flags.
  893.  
  894.          SelWriteUser          : STRPTR
  895.                manipulate another user's user-flags. You must specify the
  896.        users name (or alias).
  897.  
  898.          SelWriteGlobal,   SelWriteLocal   and  SelWriteUser  are  mutual
  899.        exclusive  --  you can  manipulate  only one flag-table at a time.
  900.        When  specifying  none  of  these  tags,  your  user-flags will be
  901.        manipulated as default.
  902.  
  903.          SelSet,
  904.          SelUnset              : LONGBITS
  905.                on  each selected message the 'SelUnset' flags are cleared
  906.        and then the 'SelSet' flags are set.
  907.        ['status = (status & ~unset) | set;']
  908.                When writing global- or user-flags, you are not allowed to
  909.        manipulate all possible flags.  See <ums.h> for protected flags.
  910.  
  911.  
  912.          The  following  tags control what and how messages are selected,
  913.        the 'input' and 'modes' of the select operation.
  914.  
  915.          SelStart,
  916.          SelStop               : LONG
  917.                Limit  the number of messages to be processed.  The select
  918.        operation  will start with the message indicated by 'SelStart' and
  919.        stop  before  the  'SelStop'  message.   In  other words, start is
  920.        included  and  stop  is  excluded.
  921.                (0 < start <= messages to be processed < stop)
  922.                This  was different and partly buggy in MBP versions prior
  923.        to V10.16.
  924.                If  no  'SelStart' is specified, the operation starts with
  925.        the  first  message;  if  no 'SelStop' is specified, the operation
  926.        stops at the last existing message.
  927.  
  928.  
  929.          The following seven operations are mutually exclusive:
  930.  
  931.        1) select by status
  932.  
  933.          SelReadGlobal         : (none)
  934.          SelReadLocal          : (none)
  935.          SelReadUser           : STRPTR
  936.                like   SelWriteGlobal,  SelWriteLocal,  SelWriteUser,  but
  937.        specifys  which  flags to look at.  Again, your user-flags are the
  938.        default.
  939.  
  940.          SelMask,
  941.          SelMatch              : LONGBITS
  942.                specify  a  mask and a match.  If (status & mask) == match
  943.        [status * mask = match], the message will be selected.
  944.  
  945.          SelParent             : (node)
  946.               with   this   tag   specified,   each   message's  'parent'
  947.        (reference;  ->  reply-chaining)  will be inspected instead of its
  948.        own status.
  949.  
  950.        2) select by date
  951.  
  952.          SelDate               : LONG
  953.                the  messages'  dates  are compared with the supplied date
  954.        (in  seconds  since  1.1.1978)  and  only the younger ones will be
  955.        selected.
  956.  
  957.        4) select a tree
  958.  
  959.          SelTree               : LONG
  960.                you  must specify  the number of a message here.  Then all
  961.        messages being in the same reply-tree will be selected.
  962.  
  963.        5) select a sub-tree
  964.  
  965.          SelSubTree            : LONG
  966.                like  SelTree,  but  only  the  subtree  (the one with the
  967.        specified message as its root) is selected.
  968.  
  969.        6) select a single message
  970.  
  971.          SelMsg                : LONG
  972.                select only the specified message.
  973.  
  974.        7) select by text
  975.  
  976.          WMsgText, ..
  977.          WMsgText + 127        : STRPTR
  978.                when  you  specify one of these tags, the function selects
  979.        all  messages  which  have  the  supplied  string in the specified
  980.        field.  The strings are compared case-INsensitive.
  981.  
  982.          SelQuick              : (none)
  983.                when  this tag is specified, 'quick-search' is enabled for
  984.        selecting  texts.  This means that only some CRCs on the texts are
  985.        compared.   This  makes  it  possible  to  select  also some wrong
  986.        messages.   Yet,  due to the usage of 32-bit CRCs, the probability
  987.        of  selecting  wrong  messages  is  VERY low, you most likely will
  988.        never experience this case.
  989.                As  'quick-search'  does  not usually need to access mass-
  990.        storage, it is VERY FAST.
  991.  
  992.    RESULT
  993.        count - how many messages have been selected.  Zero, when no
  994.                message has been selected or an error has occured.
  995.  
  996.    EXAMPLE
  997.          See SelectMail.c for examples on how to use this function.
  998.  
  999.    NOTES
  1000.          Although  LONGBITS  are  used  in  the  definition,  the current
  1001.        implementation only uses/supports the lower 16 bits.
  1002.  
  1003.    SEE ALSO
  1004.        UMSSearch(), <usm.h>, </demo/SelectMail.c>
  1005.  
  1006. ums.library/WriteUMSConfig                         ums.library/WriteUMSConfig
  1007.  
  1008.    NAME
  1009.        WriteUMSConfig -- Write an element to the global configuration.
  1010.  
  1011.    SYNOPSIS
  1012.        success = WriteUMSConfig( login, tags )
  1013.          D0                       D2     D3
  1014.  
  1015.        BOOL WriteUMSConfig( LONG, struct TagIten * );
  1016.  
  1017.        success = WriteUMSConfigTags( login, tag1, ... )
  1018.  
  1019.        BOOL WriteUMSConfigTags( LONG, ULONG, ... );
  1020.  
  1021.    FUNCTION
  1022.          Write or change something in the global UMS configuration.
  1023.  
  1024.    INPUTS
  1025.          Allowed tags:
  1026.  
  1027.          CfgData               : STRPTR
  1028.                this tag holds the data to be written to a string.
  1029.  
  1030.          CfgUser               : STRPTR
  1031.                name of the user whose config should be changed.
  1032.  
  1033.          CfgGlobalOnly         : (none)
  1034.                change only global config elements.
  1035.  
  1036.  
  1037.          The  following  tags are mutually exclusive.  Use exactly one of
  1038.        them.
  1039.  
  1040.          CfgName               : STRPTR
  1041.                Name of the string that should be changed.  If it does not
  1042.        already   exist,   the   string   will  be  created.   If  no  tag
  1043.        CfgData is specified, then the string will be deleted.
  1044.  
  1045.          CfgDump               : STRPTR
  1046.                write the current settings to a file with given name.
  1047.  
  1048.    RESULT
  1049.        success - whether it was possible and allowed to make the desired
  1050.                  write or change.
  1051.  
  1052.    BUGS
  1053.          This  function  should  provide  tags to create or delete users,
  1054.        netgroups,  akas,  etc.   These are not implemented yet.  Tell the
  1055.        author (Martin Horneffer) when you need them!
  1056.  
  1057.    SEE ALSO
  1058.        ReadUMSConfig()
  1059.  
  1060. ums.library/WriteUMSMsg                               ums.library/WriteUMSMsg
  1061.  
  1062.    NAME
  1063.        WriteUMSMsg -- Write a universal message to the UMS-MB.
  1064.  
  1065.    SYNOPSIS
  1066.        msgNum = WriteUMSMsg( login, tags )
  1067.          D0                   D3     D3
  1068.  
  1069.        LONG WriteUMSMsg( LONG, struct TagItem * );
  1070.  
  1071.        msgNum = WriteUMSMsgTags( login, tag1, ... )
  1072.  
  1073.        LONG WriteUMSMsgTags( LONG, ULONG, ... );
  1074.  
  1075.    FUNCTION
  1076.          Writes  a message to the UMS message-base.  This may be either a
  1077.        new  message  to  create  or  an  already  existing  message to be
  1078.        changed.
  1079.  
  1080.          The  MBP  checks  correctness  of  the  message  and  the  users
  1081.        write-access  concerning  this message before writing it.  It also
  1082.        performs  dupe-checking,  tries to link to a tree of reply-chains,
  1083.        creates   all  desired  indices  and  computes  the  other  users'
  1084.        read-access to this message.
  1085.          All  the components of the message as well as information on how
  1086.        to do it are supplied as AmigaDOS compatible TagItems.
  1087.  
  1088.    INPUTS
  1089.          The following tags are allowed:
  1090.  
  1091.          WMsgText, ..
  1092.          WMsgText + 127        : STRPTR
  1093.                specify a certain text-field.
  1094.                A  text fields is always one null-terminated string.  Read
  1095.        the  separate documantation to see what fields and what formats of
  1096.        these fields are allowed.
  1097.                A  certain  text-field  (identified  by  its tag) may only
  1098.        appear  once in a message.  If a field is specified more than once
  1099.        in the tag list, only the latest will be used.
  1100.  
  1101.          WTextFields           : UMSMsgTextFields
  1102.                specify more than one text-field.  This points to an array
  1103.        of 128 string-pointers.  All fields you don't want to specify must
  1104.        be NULL in this array.
  1105.  
  1106.  
  1107.          WMsgNum               : LONG
  1108.                when  you want to change an old message, you must use this
  1109.        tag  to  specify  the  number of the message to change.  Don't use
  1110.        this tag when you just want to create a new message.
  1111.  
  1112.          WMsgDate              : LONG
  1113.                this  has  a very special meaning.  Specifying an AmigaDOS
  1114.        compatible  date  (seconds since 1.1.1978) with this tag indicates
  1115.        that you  want to restore an old message from a backup rather than
  1116.        writing a new one.  All users will have the 'old' flag set and not
  1117.        get this message as a new one when this tag is used.
  1118.  
  1119.        WChainUp                : LONG
  1120.                in some cases it might be unsure or impossible for the MBP
  1121.        to  build  the correct reply-chain for a message.  Use this tag to
  1122.        specify  the  number of the old message that is referred to by the
  1123.        new one.
  1124.  
  1125.        WHardLink,
  1126.        WSoftLink               : LONG
  1127.                Writing a message with a Message-ID that already exists in
  1128.        the  MB  usually  will  lead to the detection of a 'dupe'.  Yet in
  1129.        some cases it is necessary for UMS to allow multiple messages with
  1130.        the  same  Message-ID.
  1131.                This  is  made possible by the concept of message-'links'.
  1132.        With  this  concept, multiple messages sharing the same Message-ID
  1133.        (and  perhaps some more fields) are organized in a circular linked
  1134.        list.   To  create  such  a  linked list, you just write its first
  1135.        message  as  usual  and  remember  its number.  Then you write the
  1136.        other  messages  using one of the above tags to specify the number
  1137.        of the original message (or any of the already linked messages).
  1138.                The  MBP  may  optimize storage space for message links by
  1139.        only  storing  the  fields  that differ between the fields and the
  1140.        original  message.   Nevertheless  you  always have to specify the
  1141.        whole message to write a link and you will always get the complete
  1142.        message when reading a link.
  1143.                All  links to a message must consist of the same fields as
  1144.        the original message, but the contents of the fields may differ.
  1145.  
  1146.                There  are  two  sorts  of  message-links,  hardlinks  and
  1147.        softlinks.   Softlinks  describe messages that have some fields in
  1148.        common  (at  least  the  Message-ID),  but  are  really treated as
  1149.        individual  messages.   E.g.   different parts of a splitted large
  1150.        message.  Hardlinks, on the other hand, are treated as one message
  1151.        wherever  possible.  I.e.  if you read one hardlinked message, all
  1152.        the  other  links  will be marked as old, too.  RFC crosspostings,
  1153.        for instance, should be made hardlinks.
  1154.  
  1155.        WAutoBounce             : LONG
  1156.                If the msg to be written is addressed to a local user that
  1157.        doesn't  exist or to an address that no exporter can export, there
  1158.        are two possible behaviours possible for the MBP:
  1159.                a) reject the message using error-no "NoReader", expecting
  1160.        the client to care about the undeliverable message
  1161.                b)  keep  the message, forwarding it to the local sysop or
  1162.        some kind of 'bounce-daemon', so that the writing client needs not
  1163.        to care about the message any more.
  1164.                This  tag allowes to specify the desired behaviour, data=0
  1165.        forces  a),  data=1  forces b).  If this tag is not specified, the
  1166.        MBP  will  choose  the  behaviour as it wishes, maybe depending on
  1167.        whether the writing user is an exporter or not.
  1168.  
  1169.        WHide                   : LONG
  1170.                In  some  cases  it  might be desirable to write a message
  1171.        that can only by read by exporters and not by simple users, or the
  1172.        other way round.
  1173.                For  instance  control-messages that are of no interest to
  1174.        users by must be distributed over the net.
  1175.                Setting data to 0 is the same as the default. data=1 means
  1176.        that  only  exporters  may view and read the message, data=2 makes
  1177.        the  message  invisible to exporters and only accessible to simple
  1178.        users.
  1179.  
  1180.        WHdrFill,
  1181.        WTxtFill                : LONG
  1182.                specify how many bytes to reserve for later changes in the
  1183.        header/text of the message.
  1184.                The  MBP  may not be able to change an existing message if
  1185.        the   change   would   increase  the  overall  size  (maybe  after
  1186.        compression) of the message.  Since such changes are neccessary in
  1187.        some special cases, the MBP can be told to reserve some space when
  1188.        writing a message the first time.
  1189.  
  1190.                Reserving  more  than  actually needed is not a good idea,
  1191.        since  it decreases performance and wastes space.  The writer of a
  1192.        message  usually  should  know  whether  or not he will change the
  1193.        message  later on  and to what extend he will increase the size of
  1194.        the message.
  1195.  
  1196.          WNoUpdate        : LONG
  1197.            when writing a message, the 'Old'-flag in your user-status
  1198.        for  the new message will usually be set.  If you don't want this,
  1199.        use this tag and set its data to 1.
  1200.  
  1201.    RESULT
  1202.        msgNum - Number of the written message or NULL on failure.
  1203.  
  1204.    NOTES
  1205.                Changing an old message:
  1206.  
  1207.                You   must   _always_   give   a   complete   message   to
  1208.        WriteUMSMsg(),  even when changing an old one!  The MBP needs this
  1209.        to  detect all changes made to the old message, including changed,
  1210.        added or deleted fields.  Thus you need to read a message prior to
  1211.        changing  it.  Use RTextFields and WTextField for ReadUMSMsg() and
  1212.        WriteUMSMsg()  when  changing  an old message!  Otherwise you will
  1213.        loose  fields  unknown  to  you  allication  that  might  be still
  1214.        important to other applications!
  1215.  
  1216.                You  may  not  be  allowed  to change certain fields of an
  1217.        existing  message.   Most likely those fields that are used by the
  1218.        MBP  to  compute all the users access-rights will be prohibited to
  1219.        change.
  1220.  
  1221.    SEE ALSO
  1222.        utility/tagitem.h
  1223.  
  1224.